package probe.logic;


public class Date implements Comparable<Date>{
	public enum DayOfTheWeek
	{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY}
	private int day;
	private int month;
	private int year;
	private DayOfTheWeek weekDay;
	private static final int[] dayOfTheMonth ={31,28,31,30,31,30,31,31,30,31,30,31};
	/*
	 * null constructor
	 */
	public Date(){
	}
	/*
	 * constructor for the Date class from a string
	 * currently accepted format dd/mm/yy
	 * planned accepted format dd/mm
	 */
	public Date(String dateString) throws NumberFormatException {

		if (dateString==null) return;
		
		String[] value = dateString.split("/");
		this.day = Integer.parseInt(value[0]);
		this.month = Integer.parseInt(value[1]);
		this.year = Integer.parseInt(value[2]);
		this.weekDay = calculateWeekDay(this.day,this.month,this.year);
	}
	public Date(int day, int month, int year){
		this.day = day;
		this.month = month;
		this.year = year;
		this.weekDay = calculateWeekDay(day,month,year);
	}
	/*
	 * getter methods
	 */
	public int getDay(){
		return day;
	}

	public int getMonth(){
		return month;
	}

	public int getYear(){
		return year;
	}
	public DayOfTheWeek getWeekDay (){
		return weekDay;
	}
	/*
	 * setter methods
	 */
	public void setDay(int newDay){
		this.day = newDay;
		weekDay = calculateWeekDay(day,month,year);
	}
	public void setMonth(int newMonth){
		this.month = newMonth;
		weekDay = calculateWeekDay(day,month,year);
	}
	public void setYear(int newYear){
		this.year = newYear;
		weekDay = calculateWeekDay(day,month,year);
	}
	/*
	 * 
	 */
	public Date stringToDate(String dateString){
		return null;
	}
	/*
	 * convert the date format to a String, format DDMMYY, separated by a /
	 */
	
	public String dateToStringDDMMYY(){
		String strDate = null;
		strDate = Integer.toString(day)+"/"+Integer.toString(month)+"/"+Integer.toString(year);
		return strDate;
	}
	/*
	 * convert the date format to a String, format DDMM, separated by a /
	 */
	public String dateToStringDDMM(){
		String strDate = null;
		strDate = Integer.toString(day)+"/"+Integer.toString(month);
		return strDate;
	}
	/*
	 * convert the date format to a String, format Weekday DDMMYY, separated by a /
	 */
	public String dateToStringDDMMYYwithWeekday(){
		String strDate = null;
		switch (weekDay){
		case SUNDAY:strDate = "Sunday "; break;
		case MONDAY:strDate = "Monday "; break;
		case TUESDAY:strDate = "Tuesday "; break;
		case WEDNESDAY:strDate = "Wednesday "; break;
		case THURSDAY:strDate = "Thursday "; break;
		case FRIDAY:strDate = "Friday "; break;
		case SATURDAY:strDate = "Saturday "; break;
		default:;
		}
		strDate = strDate + Integer.toString(day)+"/"+Integer.toString(month)+"/"+Integer.toString(year);
		return strDate;
	}
	/*
	 * Calculate the weekday from the Date
	 */
	private DayOfTheWeek calculateWeekDay(int day, int month, int year) {
		int count = 0;
		boolean isLeapYear = isLeapYear(year);
		
		count = year;
		count = count + (year-1)/4;
		count = count - (year-1)/100;
		count = count + (year-1)/400;
		for (int i=0;i<month-1;i++) count = count+dayOfTheMonth[i];
		if ((month>2)&&(isLeapYear))
			count++;
		count = count+day-1;
		count = count%7;
		
		switch (count){
		case 0: return DayOfTheWeek.SUNDAY;
		case 1: return DayOfTheWeek.MONDAY;
		case 2: return DayOfTheWeek.TUESDAY;
		case 3: return DayOfTheWeek.WEDNESDAY;
		case 4: return DayOfTheWeek.THURSDAY;
		case 5: return DayOfTheWeek.FRIDAY;
		case 6: return DayOfTheWeek.SATURDAY;
		default: return null;
		}
	}
	/*
	 * check if a year is a leap year or not
	 */
	private boolean isLeapYear(int year) {
		boolean isLeapYear = false;
		if (year%4 ==0){
			isLeapYear = true;
			if (year%100 == 0){
				if (year%400 == 0) 
					isLeapYear = true;
				else isLeapYear=false;
			}
		}
		else isLeapYear = false;
		return isLeapYear;
	}
	public boolean isValidDate(){
		if ((day<1)||(month<1)||(year<0))
			return false;
		if (month>12)
			return false;
		if (isLeapYear(year)){
			if (month==2)
				if (day>29) return false;
		} else if (day > dayOfTheMonth[month-1]) 
			return false;
		return true;
	}
	
	public boolean isSameDate(Date date){
		if (this.day!=date.day) 
			return false;
		if (this.month!=date.month) 
			return false;
		if (this.year!=date.year) 
			return false;
		return true;
	}
	
	@Override
	public String toString(){
		return dateToStringDDMMYY();
	}
	@Override
	public int compareTo(Date newDate) {
		if (newDate.year > this.year) return -1;
		if (newDate.year < this.year) return 1;
		if (newDate.year == this.year){
			if (newDate.month > this.month) return -1;
			if (newDate.month < this.month) return 1;
			if (newDate.month == this.year){
				if (newDate.day > this.day) return -1;
				if (newDate.day < this.day) return 1;
			}
		}
		return 0;
	}
	
}
